package com.ptrans;

import static com.ptrans.utilities.CommonUtilities.*;

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.ptrans.modele.User;
import com.ptrans.server.RegisterHandler;
import com.ptrans.server.ServerHttp;
import com.ptrans.utilities.CommonUtilities;
/**
 * This activity represent the screen when the user start the application.
 * @author Jean
 *
 */
public class HomeActivity extends Activity {

	private Context context;
	private GoogleCloudMessaging gcm;
	private String regId;
	private User user;
	private SharedPreferences prefs;
	private GCMBroadcastReceiver gcmReceiver;
	private boolean b = false;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.launcher);

        user = new User();
        
        context = getApplicationContext();
        prefs = PreferenceManager.getDefaultSharedPreferences(context);
        
        gcmReceiver = new GCMBroadcastReceiver();
        
        // Check device for Play Service APK.
        if(checkPlayServices()) {
        	gcm = GoogleCloudMessaging.getInstance(this);
        	
        	// get name and mail user, as a auth. process...
        	if(!isUserInfo()) setUserInfo();
        	else setUserOnlineInBackground();
        	
        } else {
        	Log.i(TAG, "No valid Google Play Services APK found.");
        }
    }
    
    protected void onDestroy() {
    	super.onDestroy();
    }
    
    /**
     * This method launch the screen for taking a picture
     */
    private void setUserInfo(){
    	Intent setUserIntent = new Intent(this, SetUserActivity.class);
    	startActivityForResult(setUserIntent, 1);
    }
    
    /**
     * Here we retrieve the data from the SetUserActivity
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	  if (requestCode == 1) {
	     if(resultCode == RESULT_OK){      
	         user = data.getExtras().getParcelable(CommonUtilities.EXTRA_USER);
	         registrationUserInBackground();
	     } else if (resultCode == RESULT_CANCELED) {    
	    	 Log.i(TAG, "A error was occured during the setting user info...");
	     }
	  }
	}

    /**
     * Get the user's info
     */
    private boolean isUserInfo() {
    	user.setName(prefs.getString(PROPERTY_USER_NAME, ""));
    	user.setPicture(prefs.getString(PROPERTY_USER_PICTURE, ""));
 
    	if(user.getName().isEmpty() || user.getPicture().isEmpty()) return false;
    	return true;
    }
    
    /**
     * @return Application's version code from the {@PackageManager}.
     */
    private static int getAppVersion(Context context) {
    	try {
    		PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),  0);
    		return packageInfo.versionCode;
    	} catch (NameNotFoundException e) {
    		throw new RuntimeException("Could not get package name : " + e);
    	}
    }
    
    /**
     * Register the user on the server in an asynchrone task.
     */
    private void registrationUserInBackground() {
    	new AsyncTask<Object, Object, Boolean>() {
    		
    		protected Boolean doInBackground(Object... params) {
    			String msg = "";
    			b = RegisterHandler.register(context, user);
    			
    			if(b) {
    				storeDataPreference(context, user);
    				msg = "Registration user successed";
    			} else msg = "Registration user failed";
    			Log.i(CommonUtilities.TAG, msg);
    			
    			return b;
    		}
    		
    		protected void onPostExecute(Boolean bool) {
    			if(bool.booleanValue()) {
    				uploadUserPictureInBackground();
    				setUserOnlineInBackground();
            		Toast.makeText(getApplicationContext(), getString(R.string.user_registered), Toast.LENGTH_SHORT).show();
            	}
            	else {
            		Toast.makeText(getApplicationContext(), getString(R.string.user_registration_error), Toast.LENGTH_SHORT).show();
            	}
    		}
    	}.execute(null, null, null);
    }
    
    /**
     * upload user picture on server in an asynchrone task.
     */
    private void uploadUserPictureInBackground() {
    	new AsyncTask<Object, Object, Boolean>() {
    		
    		protected Boolean doInBackground(Object... params) {
    			String msg = "";
    			b = RegisterHandler.uploadUserPicture(context, user);
    			if(b) {
    				msg = "Upload user picture successed";
    			} else msg = "Upload user picture failed";
    			Log.i(CommonUtilities.TAG, msg);
    			
    			return b;
    		}
    		
    		protected void onPostExecute(Boolean bool) {
    			if(bool.booleanValue()) {
            		Toast.makeText(getApplicationContext(), getString(R.string.img_uploaded), Toast.LENGTH_SHORT).show();
            	}
            	else {
            		Toast.makeText(getApplicationContext(), getString(R.string.img_uploaded_error), Toast.LENGTH_SHORT).show();
            	}
    		}
    	}.execute(null, null, null);
    }
    
    
    /**
     * Set the user online on the server in an asynchrone task
     */
    private void setUserOnlineInBackground() {
    	new AsyncTask<Object, Object, Boolean>() {
    		
    		protected Boolean doInBackground(Object... params) {
    			String msg = "";
    			try {
    				if(gcm == null) {
    					gcm = GoogleCloudMessaging.getInstance(context);
    				}
    				regId = gcm.register(CommonUtilities.SENDER_ID);
    				user.setRegId(regId);
    				
    				b = RegisterHandler.connect(context, user);
    				if(b) msg = "User connected, registration ID=" + regId;
    				else {
    					msg = "An error was occurred on user's connection";
    				}
    			} catch (IOException e) {
    				msg = "Error :" + e.getMessage();
    			}
    			Log.i(CommonUtilities.TAG, msg);
    			return b;
    		}
    		
    		protected void onPostExecute(Boolean b) {
    			Log.v(CommonUtilities.TAG, "Switching to main activity !");
            	if(b.booleanValue()) {
            		Toast.makeText(getApplicationContext(), getString(R.string.user_connected), Toast.LENGTH_SHORT).show();
            	}
            	else {
            		Toast.makeText(getApplicationContext(), getString(R.string.user_connection_error), Toast.LENGTH_SHORT).show();
            	}
        		activitySwitch();
    		}
    	}.execute(null, null, null);
    }
   
        
    /**
     * Stores the registration ID and app versionCode in the application's {@code SharedPreferences}.
     * 
     * @param context application's context
     * @param regId registration ID
     */
    private void storeDataPreference(Context context, User u) {
    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    	int appVersion = getAppVersion(context);
    	Log.i(CommonUtilities.TAG, "Saving Preference Data...");
    	Editor pEditor = prefs.edit();
    	pEditor.putInt(PROPERTY_APP_VERSION, appVersion);
    	pEditor.putString(PROPERTY_USER_NAME, u.getName());
    	pEditor.putString(PROPERTY_USER_PICTURE, u.getPicture());
    	pEditor.apply();
    }
    
    /**
     * Check if the devices is registered on Google Play
     * @return true if it is registered, false else
     */
    private boolean checkPlayServices() {
    	int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    	if(resultCode != ConnectionResult.SUCCESS){
    		if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
    			GooglePlayServicesUtil.getErrorDialog(resultCode, this, PLAY_SERVICES_RESOLUTION_REQUEST).show();
    		} else {
    			Log.i(CommonUtilities.TAG, "This Device is not supported");
    			finish();
    		}
    		return false;
    	}
    	return true;
    }
    
    /**
     * Method allowing to switch top an another activity
     */
    public void activitySwitch() {
        Intent intent;
		intent = new Intent(HomeActivity.this, MainActivity.class);
		intent.putExtra(CommonUtilities.EXTRA_USER, user);
		startActivity(intent);
		finish();
    }
    
}
